﻿package rob.maths{
	import rob.data.Vect3d;
	import flash.geom.Point;
	
	public class VectorMaths{
		
		public function VectorMaths():void{
		}
		
		public static var degToRad:Number = Math.PI / 180;
		
		public static function length(v:Vect3d):Number{
			return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
		}
		
		// taxi-cab metric
		public static function lenTaxi(v:Vect3d):Number{
			return Math.abs(v.x) + Math.abs(v.y) + Math.abs(v.z);
		}
		
		public static function negate(v:Vect3d):Number{
			v.x = -v.x;	v.y = -v.y;	v.z = -v.z;
		}
		
		public static function normalise(v:Vect3d):void{
			var l:Number = VectorMaths.length(v);
			if(l != 0){ v.x /= l;	v.y /= l;	v.z /= l;}
		}
		
		public static function sub(v:Vect3d,w:Vect3d):Vect3d{
			return new Vect3d(v.x - w.x,v.y - w.y,v.z - w.z);
		}
		
		public static function subTo(v:Vect3d,w:Vect3d):Vect3d{
			v.x -= w.x;	v.y -= w.y;	v.z -= w.z;
		}
		
		public static function addTo(v:Vect3d,w:Vect3d):void{
			v.x += w.x;	v.y += w.y;	v.z += w.z;
		}
		
		public static function scaleTo(k:Number,v:Vect3d):void{
			v.x *= k;	v.y *= k;	v.z *= k;
		}
		
		public static function scaleNew(k:Number,v:Vect3d):Vect3d{
			return new Vect3d(v.x * k,v.y * k,v.z * k);
		}
		
		public static function dp(v:Vect3d,w:Vect3d):Number{
			return v.x * w.x + v.y * w.y + v.z * w.z;
		}
		
		public static function cp(v:Vect3d,w:Vect3d):Vect3d{
			var c:Vect3d = new Vect3d(0,0,0);
			c.x = v.y * w.z - v.z * w.y;
			c.y = v.z * w.x - v.x * w.z;
			c.z = v.x * w.y - v.y * w.x;
			return c;
		}
		
		public static function average(a:Array):Vect3d{
			var avg:Vect3d = new Vect3d(0,0,0);
			for each(var p:Vect3d in a) VectorMaths.addTo(avg,p);
			VectorMaths.scaleTo(1/a.length,avg);
			return avg;
		}
		
		// we only rotate in plane y = constant (anti-clockwise from above)
		public static function rotateBy(dtheta:Number,v:Vect3d):void{
			var vx:Number = v.x, vz:Number = v.z; 
			v.z = Math.cos(dtheta) * vz - Math.sin(dtheta) * vx;
			v.x = Math.sin(dtheta) * vz + Math.cos(dtheta) * vx;
		}

		// we only rotate in plane y = constant (anti-clockwise from above)
		public static function rotateByNew(dtheta:Number,v:Vect3d):Vect3d{
			var w:Vect3d = v.clone(); 
			w.z = Math.cos(dtheta) * v.z - Math.sin(dtheta) * v.x;
			w.x = Math.sin(dtheta) * v.z + Math.cos(dtheta) * v.x;
			return w;
		}
		
		
	}
}